#include "Scope.h"
#include "../ModulesMgr.h"
#include "FunctionScope.h"
#include "ClassScope.h"

Scope::Scope(Scope* parentScope, const QFileInfo& fileName):
    PyName(parentScope, fileName)
{
}

Scope::~Scope()
{
    qDeleteAll(_childScopes);
    //qDeleteAll(_names);
    _names.clear();
}

QFileInfo Scope::fileName()
{
    return _fileName;
}

void Scope::visitImport(const ImportPtr &node)
{
    foreach(aliasTypePtr alias, node->names()){
        Scope *mod = (Scope*)ModulesMgr::instance().moduleByName(alias->name()->id(), _fileName.absolutePath());
        if (alias->asname() && !alias->asname()->id().isEmpty())
            _names.insert(alias->asname()->id(), mod);
        else
            _names.insert(alias->name()->id(), mod);
    }
}

void Scope::visitImportFrom(const ImportFromPtr &node)
{
    Scope *mod = NULL;
    if (!node->module()->id().isEmpty()) {
        mod = (Scope*)ModulesMgr::instance().moduleByName(node->module()->id(), _fileName.absolutePath());
    } else {
        qDebug() << _fileName.absoluteFilePath();
    }
    if (!mod)
        return;

    if (!node->names().length()){
        // import *
        //TODO: warning, import *
        foreach(QString name, mod->_names.keys()){
            _names.insert(name, mod->_names.value(name));
        }
    } else {
        foreach(aliasTypePtr alias, node->names()){
            if (mod->_names.contains(alias->name()->id()))
                _names.insert(alias->name()->id(), mod->_names.value(alias->name()->id()));
        }
    }
}

void Scope::visitFunctionDef(const FunctionDefPtr &node)
{
    FunctionScope * fnc = new FunctionScope(node, this);
    _names.insert(node->name()->id(), fnc);
    _childScopes.append(fnc);
}

void Scope::visitClassDef(const ClassDefPtr &node)
{
    ClassScope *cls = new ClassScope(node, this);
    _names.insert(node->name()->id(), cls);
    _childScopes.append(cls);
}

void Scope::visitAssign(const AssignPtr &node)
{
}

void Scope::itemAtPos(int pos)
{
    qDebug() << pos;
}

/*void Scope::unhandled_node(const SimpleNodePtr& node)
{
    qDebug() << node->toString();
}*/
